package com.glink.manage.mqtt.common;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.TrustAllStrategy;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.util.EntityUtils;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.NoSuchAlgorithmException;
import java.util.Map;
import java.util.Objects;

/**
 * Created by IntelliJ IDEA.
 *
 * @Author : qiushaoshan
 * @create 2024/7/30 18:51
 */
@Slf4j
@Component
public class HttpClientUtil {
    
    private static CloseableHttpClient httpClient;
    
    private static PoolingHttpClientConnectionManager poolConnManager = null;

    static {
        try {
            SSLContextBuilder builder = new SSLContextBuilder();
            builder.loadTrustMaterial(null, new TrustAllStrategy());

            poolConnManager = new PoolingHttpClientConnectionManager();

            poolConnManager.setMaxTotal(HttpClientConfig.MAX_TOTAL);

            poolConnManager.setDefaultMaxPerRoute(HttpClientConfig.MAX_PER_ROUTE);

            httpClient = getConnection();
        } catch (NoSuchAlgorithmException | java.security.KeyStoreException e) {
            e.printStackTrace();
        }
    }

    private static CloseableHttpClient getConnection() {
        RequestConfig config = RequestConfig.custom().setConnectTimeout(HttpClientConfig.CONNECT_TIMEOUT).setConnectionRequestTimeout(HttpClientConfig.REQUEST_TIMEOUT).setSocketTimeout(HttpClientConfig.SOCKET_TIMEOUT).build();
        return HttpClients.custom().setConnectionManager(poolConnManager)
                .setDefaultRequestConfig(config)
                .setRetryHandler(new DefaultHttpRequestRetryHandler(HttpClientConfig.RETRY_COUNT, false)).build();
    }

    public static JSONObject httpPost(String url, Object jsonParam) {
        JSONObject jsonResult = null;
        try {
            String str = post(null, url, JSON.toJSONString(jsonParam));
            if (str != null) {
                jsonResult = JSONObject.parseObject(str);
            }
        } catch (Exception e) {
            log.error("post请求提交失败:,{}" + url, e.getMessage());
        }
        return jsonResult;
    }

    public static String post(Map<String, String> headers, String uri, String params) {
        log.info("httpPost start:url={}，jsonParam= {}", uri, params);
        HttpPost httpPost = new HttpPost(uri);
        CloseableHttpResponse response = null;
        try {
            if (headers != null) {
                for (Map.Entry<String, String> entry : headers.entrySet()) {
                    httpPost.setHeader(entry.getKey(), entry.getValue());
                }
            }
            params = (params == null) ? "" : params;
            StringEntity paramEntity = new StringEntity(params, StandardCharsets.UTF_8);
            paramEntity.setContentEncoding(StandardCharsets.UTF_8.toString());
            paramEntity.setContentType("application/json");
            httpPost.setEntity(paramEntity);
            response = httpClient.execute(httpPost);
            int code = response.getStatusLine().getStatusCode();
            String result = EntityUtils.toString(response.getEntity());
            if (code == 200) {
                return result;
            }
            httpPost.abort();
            log.error("请求{}返回错误码:{},请求参数:{},{}", new Object[]{uri, Integer.valueOf(code), params, result});
            return null;
        } catch (IOException e) {
            httpPost.abort();
            log.error("收集服务配置http请求异常", e);
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
                httpPost.releaseConnection();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    public static boolean isSuccess(JSONObject result) {
        return (result != null && Objects.equals(String.valueOf(result.get("code")), String.valueOf("2000")));
    }
}
